package stc.skymobi.netty.handler.codec.http.encode;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import stc.skymobi.bean.tlv.TLVSignal;
import stc.skymobi.bean.tlv.annotation.HttpTLVAttribute;
import stc.skymobi.bean.tlv.encode.TLVEncodeContext;
import stc.skymobi.bean.tlv.encode.TLVEncoderOfBean;
import stc.skymobi.util.ByteUtils;

import java.util.List;

@ChannelHandler.Sharable
public class NettyMixedHttpEncoder extends MessageToMessageEncoder<TLVSignal> {
    private static final Logger logger = LoggerFactory.getLogger(NettyMixedHttpEncoder.class);
    private TLVEncoderOfBean tlvBeanEncoder;

    @Override
    public void encode(ChannelHandlerContext ctx, TLVSignal msg, List<Object> out) throws Exception {
        logger.debug("encoding HTTP TLVSignal...");
        TLVEncodeContext tlvEncodeContext =
                tlvBeanEncoder.getEncodeContextFactory().createEncodeContext(msg.getClass(), null);
        List<byte[]> byteList = tlvBeanEncoder.encode(msg, tlvEncodeContext);
        byte[] bytes = ByteUtils.union(byteList);

        String uri = "/";
        HttpTLVAttribute attr = msg.getClass().getAnnotation(HttpTLVAttribute.class);
        if (attr != null) {
            String u = attr.uri();
            uri = u.startsWith("/") ? u : ("/" + u);
        }

        FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uri);
        request.headers().set("Content-Length", bytes.length);
        request.content().writeBytes(Unpooled.wrappedBuffer(bytes));
        out.add(request);
    }

    public void setTlvBeanEncoder(TLVEncoderOfBean tlvBeanEncoder) {
        this.tlvBeanEncoder = tlvBeanEncoder;
    }
}
